package IA;

import iterators.*;
import java.util.*;
/**
 *
 * @author Christopher
 */
public class KitchenQueue {
    //actual order queue

    protected ArrayList<CookItem> itemsToCook;
    protected ArrayList<CookItem> itemsCooking;
    protected ArrayList<Integer> pastPrepTimes;
    //table number key to number of orders
    protected Map<Integer, Integer> totalTableOrders;

    public KitchenQueue() {
        itemsToCook = new ArrayList<CookItem>();
        itemsCooking = new ArrayList<CookItem>();
        pastPrepTimes = new ArrayList<Integer>();
        totalTableOrders = new HashMap<Integer, Integer>();
    }

    public ArrayList<CookItem> getQueueItems() {
        return itemsToCook;
    }

    public ArrayList<CookItem> getCookingItems() {
        return itemsCooking;
    }

    public Iterator<CookItem> getCookingItemsIterator() {
        return itemsCooking.iterator();
    }
    
    public Iterator<CookItem> getQueueItemsIterator() {
        return itemsToCook.iterator();
    }

    public Iterator<Integer> getPastPrepTimeIterator() {
        return new ReverseIterator(pastPrepTimes);
    }
    
    public int getNumCookingItems() {
        return itemsCooking.size();
    }

    public boolean add(OrderItem item) {
        CookItem ci = new CookItem(item.getPrepTime(), item.getTableID(), item.getName());
        SystemClock.getInstance().AddObserver(ci);
        itemsToCook.add(ci);
        //increment number of orders to that table or create spot for table in list
        if (totalTableOrders.get(item.getTableID()) != null) {
            Integer numTableOrders = totalTableOrders.get(item.getTableID());
            totalTableOrders.put(item.getTableID(), numTableOrders + 1);
        } else {
            totalTableOrders.put(item.getTableID(), 1);
        }
        return true;
    }

    public void startCookingItem(CookItem item, double TimeFactor) {
        item.setPrepTime((int) ((double) item.getPrepTime() * TimeFactor));
        //remove from queue and put in cooking list 
        itemsToCook.remove(item);
        itemsCooking.add(item);
    }

    public boolean finishCookingItem(CookItem item, Iterator<CookItem> itr) {
        //return true if item is last of table to be cooked
        SystemClock.getInstance().RemoveObserver(item);
        pastPrepTimes.add(item.getTotalCookTime());
        itr.remove();
        int tableItemsLeft = totalTableOrders.get(item.getTableID());
        if (--tableItemsLeft == 0) {
            totalTableOrders.remove(item.getTableID());
            return true;
        } else {
            totalTableOrders.put(item.getTableID(), tableItemsLeft);
            return false;
        }
    }

    public boolean ItemCooking(String name) {
        for (Iterator<CookItem> itr = itemsCooking.iterator(); itr.hasNext();) {
            if (itr.next().getName().equals(name)) {
                return true;
            }
        }
        return false;
    }
    //determines whether any food for a table is in the queue or on the grill
    public boolean TableInQueueOrGrill(int TableID) {
        for(int i = 0; i < itemsCooking.size(); i++) {
            if(itemsCooking.get(i).getTableID() == TableID) return true;
        }
        for(int i = 0; i < itemsToCook.size(); i++) {
            if(itemsToCook.get(i).getTableID() == TableID) return true;
        }
        return false;
    }
    
    public int getNumCookingItemsByTable(int TableID) {
        int Sum = 0;
         for(int i = 0; i < itemsCooking.size(); i++) {
            if(itemsCooking.get(i).getTableID() == TableID) Sum++;
        }
        return Sum;
    }
    
    public int getNumQueueItemsByTable(int TableID) {
        int Sum = 0;
         for(int i = 0; i < itemsToCook.size(); i++) {
            if(itemsToCook.get(i).getTableID() == TableID) Sum++;
        }
        return Sum;
    }
    
}
